#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <utility>
#include <vector>
#include <unistd.h>
#include <sys/ipc.h>

void start(std::map<int, std::pair<int*, int*> > &map_pipe, int id) {
	pid_t pid = fork();
	if (pid < 0) {
		printf("Father fork (%d) ERROR\n", id);
		return;
	}
	else if (pid > 0) return;
	
	pid = getpid();
	printf("(%d)Son pid: %d\n", id, pid);
	std::map<int, std::pair<int*, int*> >::iterator it;
	for (it = map_pipe.begin(); it != map_pipe.end(); it++) {
		int *pipe1 = it->second.first;
		int *pipe2 = it->second.second;
		close(pipe1[1]);
		close(pipe2[0]);
	}

	int in_pipe  = map_pipe[id].first[0];
	int out_pipe = map_pipe[id].second[1];
	char buff[100];
	ssize_t n;
	memset(buff, 0, sizeof(buff));
	n = read(in_pipe, buff, 100);
	printf("(%d)Son pid: %d, recv: %s\n", id, pid, buff);
	
	sprintf(buff, "hello i am your son(%d) %d\n", id, pid);
	n = write(out_pipe, buff, strlen(buff));

	sleep(30);
	printf("(%d)Son pid: %d EXIT\n", id, pid);
	exit(0);
}

int main() {
	std::map<int, std::pair<int*, int*> > map_pipe;
	map_pipe.clear();
	
	pid_t pid = getpid();
	printf("Father pid: %d\n", pid);
	
	for (int i = 0; i < 3; i++) {
		int *pipe1 = new int[2];
		int *pipe2 = new int[2];
		map_pipe[i] = std::make_pair(pipe1, pipe2);
		pipe(pipe1);
		pipe(pipe2);
		start(map_pipe, i);
		close(pipe1[0]);
		close(pipe2[1]);
	}
	
	char buff[100] = "hello i am Father";
	for (int i = 0; i < 3; i++) {
		int out_pipe = map_pipe[i].first[1];
		int in_pipe = map_pipe[i].second[0];
		ssize_t n = write(out_pipe, buff, strlen(buff));
		char recv[100];
		memset(recv, 0, sizeof(recv));
		n = read(in_pipe, recv, 100);
		printf("Father recv: %s\n", recv);
	}
	
		
	sleep(30);
	return 0;
}
